﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Geometry
{
    /// <summary>
    /// Class providing Angle from 0 to 2*PI
    /// </summary>
    public class Angle
    {
        private  double _val;
        /// <summary>
        /// Value is only from 0 to 2*PI, minus valuse are illegal
        /// </summary>
        public double val { 
            get 
            { 
                return _val; 
            }
 
            private set 
            { 
                _val = ValidEntry(value); 
            } 
        }

        public Angle()
        {
            val = 0;
        }

        public Angle(double value)
        {
            val = value;
        }

        public Angle(Angle a)
        {
            this.val = a.val;
        }

        public static Angle operator +(Angle one, Angle two)
        {
            double ret = 0;
            ret = one.val + two.val;
            ret = one.ValidEntry(ret);
            return new Angle(ret);
        }

        public static Angle operator +(double one, Angle two)
        {
            double ret = 0;
            ret = one + two.val;
            return new Angle(ret);
        }

        public static Angle operator +(Angle one, double two)
        {
            double ret = 0;
            ret = one.val + two;
            return new Angle(ret);
        }

        public static Angle operator -(Angle one, Angle two)
        {
            double ret = 0;
            ret = one.val - two.val;
            ret = one.ValidEntry(ret);
            return new Angle(ret);
        }

        public static Angle operator -(double one, Angle two)
        {
            double ret = 0;
            ret = one - two.val;
            return new Angle(ret);
        }

        public static Angle operator -(Angle one, double two)
        {
            double ret = 0;
            ret = one.val - two;
            return new Angle(ret);
        }

        public static Angle operator /(Angle one, Angle two)
        {
            double ret = one.val / two.val;
            return new Angle(ret);
        }

        public static Angle operator /(Angle one, double two)
        {
            double ret = one.val / two;
            return new Angle(ret);
        }

        public static bool operator >(Angle one, Angle two)
        {
            if (one.val > two.val) return true;
            return false;
        }

        public static bool operator >(Angle one, double two)
        {
            if (one.val > two) return true;
            return false;
        }

        public static bool operator >(double one, Angle two)
        {
            if (one > two.val) return true;
            return false;
        }

        public static bool operator <(Angle one, Angle two)
        {
            if (one.val < two.val) return true;
            return false;
        }

        public static bool operator <(double one, Angle two)
        {
            if (one < two.val) return true;
            return false;
        }

        public static bool operator <(Angle one, double two)
        {
            if (one.val < two) return true;
            return false;
        }

        public static bool operator <=(Angle one, Angle two)
        {
            if (one.val <= two.val) return true;
            return false;
        }

        public static bool operator <=(double one, Angle two)
        {
            if (one <= two.val) return true;
            return false;
        }

        public static bool operator <=(Angle one, double two)
        {
            if (one.val <= two) return true;
            return false;
        }

        public static bool operator >=(Angle one, Angle two)
        {
            if (one.val >= two.val) return true;
            return false;
        }

        public static bool operator >=(double one, Angle two)
        {
            if (one >= two.val) return true;
            return false;
        }

        public static bool operator >=(Angle one, double two)
        {
            if (one.val >= two) return true;
            return false;
        }

        public static bool operator ==(Angle one, Angle two)
        {
            if (one.val == two.val) return true;
            return false;
        }

        public static bool operator ==(double one, Angle two)
        {
            if (one. == two.val) return true;
            return false;
        }

        public static bool operator ==(Angle one, double two)
        {
            if (one.val == two) return true;
            return false;
        }

        public static bool operator !=(Angle one, Angle two)
        {
            if (one.val != two.val) return true;
            return false;
        }

        public static bool operator !=(double one, Angle two)
        {
            if (one != two.val) return true;
            return false;
        }

        public static bool operator !=(Angle one, double two)
        {
            if (one.val != two) return true;
            return false;
        }

        public double Tan()
        {
            return Math.Tan(val);
        }

        public double Sin()
        {
            return Math.Sin(val);
        }

        public double Cos()
        {
            return Math.Cos(val);
        }

        public int Quarter()
        {
            if (val >= 0 && val < Math.PI / 2) return 1;
            if (val >= Math.PI / 2 && val < Math.PI) return 2;
            if (val >= Math.PI && val < 3 * Math.PI / 2) return 3;
            if (val >= 3 * Math.PI / 2 && val < 2 * Math.PI) return 4;
            return 0;
        }

        public override string ToString()
        {
            return val.ToString();
        }

        private double ValidEntry(double entry)
        {
            double ret = entry;
            if (ret >= 0)
            {
                while (ret > Math.PI * 2)
                {
                    ret -= Math.PI * 2;
                }
            }

            if (ret < 0)
            {
                while (ret < 0)
                {
                    ret += Math.PI * 2;
                }
            }

            return ret;
        }

    } 
}
